'''

Case Type： 数据库系统
Case Name： 配置文件为空，暂停数据库进程（接收kill -19信号）
Create At:  2020/07/27
@zou_jialiang0505328126
Descption:  1. 备份配置文件
2. 清空配置文件
3. 获取pid
pgrep gaussdb
4. 停止进程
kill -19 pid
5. 连接数据库
6. 恢复进程
7. 连接数据库
8. 运行tpcc指令
9. 恢复配置文件
10. 连接数据库
11. 运行tpcc指令


history：
created： 2020/07/27  created by @wan005
'''
import os
import unittest
import time
from yat.test import Node
from yat.test import macro
import sys

sys.path.append(sys.path[0] + "/../")
from testcase.utils.Logger import Logger
from testcase.utils.Constant import Constant
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.ComThread import ComThread

logger = Logger()
common = Common()
Constant = Constant()


class StopImmediate(unittest.TestCase):
    dbPrimaryUserNode = Node(node='PrimaryDbUser')
    dbPrimaryRootNode = Node(node='PrimaryRoot')
    DB_INSTANCE_PATH = macro.DB_INSTANCE_PATH
    DB_ENV_PATH = macro.DB_ENV_PATH
    GS_CTL_STOP_SUCCESS_MSG = Constant.GS_CTL_STOP_SUCCESS_MSG
    STANDBY_NORMAL = Constant.STANDBY_NORMAL
    PRIMARY_NORMAL = Constant.PRIMARY_NORMAL
    START_SUCCESS_MSG = Constant.START_SUCCESS_MSG
    TPCC_SUCCESS_MSG = Constant.TPCC_SUCCESS_MSG
    RESTART_SUCCESS_MSG = Constant.RESTART_SUCCESS_MSG
    file_path = ''
    TPCC_PATH = macro.TPCC_PATH
    primary_sh = CommonSH('PrimaryDbUser')
    standby_1_sh = CommonSH('Standby1DbUser')
    standby_2_sh = CommonSH('Standby2DbUser')
    conffile = macro.DB_INSTANCE_PATH + '/' + macro.DB_PG_CONFIG_NAME
    conffilebak = macro.DB_INSTANCE_PATH + '/' + macro.DB_PG_CONFIG_NAME + '.baktest'
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        logger.info("-----------this is setup-----------")
        logger.info('------------Opengauss_Reliability_Dbsys_Case171.py start------------')
        logger.info("----------------------get socket file path--------------")
        time.sleep(30)
        sql = "show unix_socket_directory"
        getfilepath_msg = self.primary_sh.executDbSql(sql)
        logger.info(getfilepath_msg)
        self.file_path = getfilepath_msg.split('\n')[2]
        logger.info(self.file_path)

    def test_stop_immediate(self):
        time.sleep(30)
        logger.info("------------------copy conf file----------------------")
        delete_cmd = f'cp {self.conffile} {self.conffilebak}'
        logger.info(delete_cmd)
        self.dbPrimaryUserNode.sh(delete_cmd)
        logger.info(self.dbPrimaryUserNode.sh(f'ls -al {self.DB_INSTANCE_PATH}').result())

        logger.info("------------------clear conf file----------------------")
        delete_cmd = f'> {self.conffile}'
        logger.info(delete_cmd)
        self.dbPrimaryUserNode.sh(delete_cmd)

        logger.info("-----------------------stop pid-------------------------------")
        msg = common.kill_pid(self.dbPrimaryRootNode, '19')
        self.assertEqual(msg, '')

        logger.info("----------------------connect opengauss----------------------")
        nosocket_connect = ComThread(self.primary_sh.nosocketConnect, args=())
        nosocket_connect.setDaemon(True)
        nosocket_connect.start()

        socket_connect = ComThread(self.primary_sh.socket_connect, args=(self.file_path,))
        socket_connect.setDaemon(True)
        socket_connect.start()

        nosocket_connect.join(60 * 10)
        no_socket_connect_msg = nosocket_connect.get_result()
        logger.info('no_socket_connect_msg:' + str(no_socket_connect_msg))
        self.assertIn(Constant.TIMEOUT_EXPIRED_MSG, no_socket_connect_msg)

        socket_connect.join(60 * 10)
        socket_connect_msg = socket_connect.get_result()
        logger.info('socket_connect_msg:' + str(socket_connect_msg))
        self.assertIn(Constant.TIMEOUT_EXPIRED_MSG, no_socket_connect_msg)

        logger.info("-----------------------reconnect pid-------------------------------")
        msg = common.kill_pid(self.dbPrimaryRootNode, '18')
        self.assertEqual(msg, '')
        time.sleep(60)

        logger.info("----------------------connect opengauss----------------------")
        no_socket_connect_msg = self.primary_sh.nosocketConnect()
        logger.info(no_socket_connect_msg)
        self.assertEqual(no_socket_connect_msg, '')

        socket_connect_msg = self.primary_sh.socket_connect(self.file_path)
        logger.info(socket_connect_msg)
        self.assertEqual(socket_connect_msg, '')

        logger.info("---------------------start TPCC----------------------")
        tpcc_result = common.startTPCC(self.dbPrimaryRootNode, self.TPCC_PATH)
        logger.info('-------------' + tpcc_result + '-----------------------')
        logger.info(tpcc_result)
        self.assertTrue(tpcc_result.find(self.TPCC_SUCCESS_MSG) > -1)

        logger.info("------------------------recover conf file------------------")
        recover_cmd = f'rm -f {self.conffile}'
        logger.info(recover_cmd)
        self.dbPrimaryUserNode.sh(recover_cmd)
        recover_cmd = f'mv {self.conffilebak} {self.conffile}'
        logger.info(recover_cmd)
        self.dbPrimaryRootNode.sh(recover_cmd)
        logger.info(self.dbPrimaryUserNode.sh(f'ls -al {self.DB_INSTANCE_PATH}').result())

        logger.info("----------------------connect opengauss----------------------")
        no_socket_connect_msg = self.primary_sh.nosocketConnect()
        logger.info(no_socket_connect_msg)
        self.assertEqual(no_socket_connect_msg, '')

        socket_connect_msg = self.primary_sh.socket_connect(self.file_path)
        logger.info(socket_connect_msg)
        logger.info(type(socket_connect_msg))
        self.assertEqual(socket_connect_msg, '')

        logger.info("---------------------start TPCC----------------------")
        tpcc_result = common.startTPCC(self.dbPrimaryRootNode, self.TPCC_PATH)
        logger.info('-------------' + tpcc_result + '-----------------------')
        logger.info(tpcc_result)
        self.assertTrue(tpcc_result.find(self.TPCC_SUCCESS_MSG) > -1)

        logger.info("------------------------recover socket file------------------")
        recover_cmd = f'mv {self.conffilebak} {self.conffile}'
        logger.info(recover_cmd)
        self.dbPrimaryUserNode.sh(recover_cmd)
        logger.info(self.dbPrimaryUserNode.sh(f'ls -al {self.DB_INSTANCE_PATH}').result())

        # 校验刷脏页是否完成
        logger.info('校验刷脏页是否完成')
        dirty_page_finshed_flag = self.primary_sh.check_whether_remain_dirty_page()
        self.assertTrue(dirty_page_finshed_flag)

        # 校验备机是否完成数据同步
        logger.info('校验备机是否完成数据同步')
        flag_1 = self.standby_1_sh.check_data_consistency()
        self.assertTrue(flag_1)
        flag_2 = self.standby_2_sh.check_data_consistency()
        self.assertTrue(flag_2)

    def tearDown(self):
        logger.info('----------------this is tearDown-----------------------')
        msg = common.kill_pid(self.dbPrimaryRootNode, '18')
        logger.info(msg)

        logger.info("------------------------recover conf file------------------")
        msg_list = self.dbPrimaryUserNode.sh(f'ls -al {self.DB_INSTANCE_PATH}').result()
        if macro.DB_PG_CONFIG_NAME + '.baktest' in msg_list:
            recover_cmd = f'rm -f {self.conffile}'
            logger.info(recover_cmd)
            self.dbPrimaryUserNode.sh(recover_cmd)
            recover_cmd = f'mv {self.conffilebak} {self.conffile}'
            logger.info(recover_cmd)
            self.dbPrimaryUserNode.sh(recover_cmd)
        else:
            pass
